package cn.platform.service.impl;

import cn.platform.entity.Parent;
import cn.platform.entity.ParentStudent;
import cn.platform.entity.Student;
import cn.platform.entity.Teacher;
import cn.platform.exception.BusinessException;
import cn.platform.mapper.*;
import cn.platform.request.*;
import cn.platform.response.PageResult;
import cn.platform.response.UserParentVO;
import cn.platform.response.UserStudentVO;
import cn.platform.response.UserTeacherVO;
import cn.platform.service.UserService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import de.mkammerer.argon2.Argon2;
import de.mkammerer.argon2.Argon2Factory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Year;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static java.util.Locale.filter;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private ClazzMapper clazzMapper;
    @Autowired
    private TeacherClassMapper teacherClassMapper;
    @Autowired
    private ParentStudentMapper parentStudentMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private ParentMapper parentMapper;

    private final Argon2 argon2 = Argon2Factory.create();

    /**
     * 条件分页查询教师
     * @param userTeacherQueryDTO
     * @return
     */
    @Override
    public PageResult<UserTeacherVO> pageTeacher(UserTeacherQueryDTO userTeacherQueryDTO) {
        PageHelper.startPage(userTeacherQueryDTO.getPage(),userTeacherQueryDTO.getPageSize());
        Page<UserTeacherVO> userTeacherPage = teacherMapper.page(userTeacherQueryDTO);
        return new PageResult<>(userTeacherPage.getTotal(),userTeacherPage.getResult());
    }

    /**
     * 新增教师
     * @param teacher
     */
    @Override
    public void saveTeacher(Teacher teacher) {
        String password = teacher.getPassword();
        String Jia_Mi_PWD = argon2.hash(2, 65536, 1, password.toCharArray());
        teacher.setPassword(Jia_Mi_PWD);
        teacherMapper.insert(teacher);
    }

    /**
     * 获取教师详细信息
     * @param id
     * @return
     */
    @Override
    public UserTeacherVO getTeacherInfo(Integer id) {
        return teacherMapper.getById(id);
    }

    /**
     * 更新教师信息
     * @param teacher
     */
    @Override
    public void updateTeacher(Teacher teacher) {
        if(teacher.getPassword()!=null && !teacher.getPassword().trim().isEmpty()){
            String password = teacher.getPassword();
            String Jia_Mi_PWD = argon2.hash(2, 65536, 1, password.toCharArray());
            teacher.setPassword(Jia_Mi_PWD);
        }else {
            teacher.setPassword(null);
        }
        teacherMapper.updateTeacher(teacher);
    }

    /**
     * 删除老师信息
     * @param id
     */
    @Override
    public void deleteTeacherById(Integer id) {
        Integer count = teacherMapper.countTeacherId(Collections.singletonList(id));
        if(count>0){
            throw new BusinessException("该教师存在关联的班级或授课记录，无法删除");
        }
        teacherMapper.deleteById(id);
    }

    /**
     * 批量删除老师信息
     * @param ids
     */
    @Override
    public void batchDeleteTeacherById(List<Integer> ids) {
        Integer count = teacherMapper.countTeacherId(ids);
        if (count>0){
            throw new BusinessException("批量删除的教师中存在关联的班级或授课记录，无法删除");
        }
        teacherMapper.batchDeleteByIds(ids);
    }

    /**
     * 实现学生信息的分页查询
     * @param userStudentQueryDTO
     * @return
     */
    @Override
    public PageResult<UserStudentVO> pageStudent(UserStudentQueryDTO userStudentQueryDTO) {
        if (userStudentQueryDTO.getGrade()!=null){
            int currentYear = Year.now().getValue();
            userStudentQueryDTO.setGradeYear(currentYear-userStudentQueryDTO.getGrade()+1);
        }

        PageHelper.startPage(userStudentQueryDTO.getPage(),userStudentQueryDTO.getPageSize());
        List<UserStudentVO> voList = studentMapper.page(userStudentQueryDTO);

        int currentYear = Year.now().getValue();
        for(UserStudentVO vo:voList){
            int gradeNum = currentYear-vo.getGradeYear()+1;
            if (gradeNum>=1 && gradeNum<=6){
                vo.setGrade(gradeNum);
            }else {
                vo.setGrade(null);
                vo.setClassNum(null);
            }
        }
        Page<UserStudentVO> page =(Page<UserStudentVO>) voList;
        return new PageResult<>(page.getTotal(),page.getResult());

    }

    /**
     * 新增学生信息
     * @param userStudentDTO
     */
    @Override
    public void saveStudent(UserStudentDTO userStudentDTO) {
        int currentYear = Year.now().getValue();
        int gradeYear = currentYear - userStudentDTO.getGrade()+1;

        String classId = clazzMapper.getClassIdByGradeAndClassNum(gradeYear,userStudentDTO.getClassNum());
        if (classId == null){
            throw new BusinessException("找不到对应的班级信息，无法添加");
        }
        Student student = new Student();
        BeanUtils.copyProperties(userStudentDTO,student);
        student.setClassID(classId);

        //给学生的密码进行加密处理
        String password = student.getPassword();
        String Jia_Mi_PWD = argon2.hash(2, 65536, 1, password.toCharArray());
        student.setPassword(Jia_Mi_PWD);
        studentMapper.insert(student);
    }

    /**
     * 更新学生信息
     * @param userStudentDTO
     */
    @Override
    public void updateStudent(UserStudentDTO userStudentDTO) {
        if(userStudentDTO.getPassword()!=null && !userStudentDTO.getPassword().trim().isEmpty()){
            String password = userStudentDTO.getPassword();
            String Jia_Mi_PWD = argon2.hash(2, 65536, 1, password.toCharArray());
            userStudentDTO.setPassword(Jia_Mi_PWD);
        }else{
            userStudentDTO.setPassword(null);
        }

        int currentYear = Year.now().getValue();
        int gradeYear = currentYear - userStudentDTO.getGrade()+1;

        String classId = clazzMapper.getClassIdByGradeAndClassNum(gradeYear,userStudentDTO.getClassNum());
        if (classId == null){
            throw new BusinessException("更新失败，找不到对应的班级信息");
        }

        Student student =new Student();
        BeanUtils.copyProperties(userStudentDTO,student);
        student.setClassID(classId);
        studentMapper.update(student);
    }

    /**
     * 删除单个学生信息
     * @param id
     */
    @Override
    public void deleteStudent(Integer id) {
        Integer count = studentMapper.countWithParentId(Collections.singletonList(id));
        if(count>0){
            throw new BusinessException("存在家长绑定该学生，无法删除，请先解除绑定");
        }
        studentMapper.deleteById(id);
    }

    /**
     * 批量删除学生信息
     * @param ids
     */
    @Override
    public void batchDeleteStudentById(List<Integer> ids) {
        Integer count = studentMapper.countWithParentId(ids);
        if(count>0){
            throw new BusinessException("存在家长绑定学生，无法删除，请先解除绑定");
        }
        studentMapper.batchDeleteById(ids);
    }

    /**
     * 用户管理，分页查询家长信息
     * @param queryDTO
     * @return
     */
    @Override
    public PageResult<UserParentVO> pageParent(UserParentQueryDTO queryDTO) {
        PageHelper.startPage(queryDTO.getPage(), queryDTO.getPageSize());
        Page<UserParentVO> parentVO = parentMapper.page(queryDTO);
        return new PageResult<>(parentVO.getTotal(),parentVO.getResult());
    }

    /**
     * 根据id获取学生姓名
     * @param studentId
     * @return
     */
    @Override
    public String getStudentNameById(Integer studentId) {
        Student student = studentMapper.selectById(studentId);
        return student !=null ? student.getRealName():null;
    }

    /**
     * 用户管理，新增家长信息
     * @param userParentDTO
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveParent(UserParentDTO userParentDTO) {
        Parent parent = new Parent();
        BeanUtils.copyProperties(userParentDTO,parent);

        String password = parent.getPassword();
        String Jia_Mi_PWD = argon2.hash(2, 65536, 1, password.toCharArray());
        parent.setPassword(Jia_Mi_PWD);

        parentMapper.insert(parent);

        if(userParentDTO.getBindings()!=null && !userParentDTO.getBindings().isEmpty()){
            List<ParentStudent> relations = userParentDTO.getBindings().stream()
                    .filter(binding -> binding.getStudentId() != null && !String.valueOf(binding.getStudentId()).isEmpty())
                    .map(binding -> new ParentStudent(null, parent.getId(), binding.getStudentId()))
                    .collect(Collectors.toList());
            if (!relations.isEmpty()) {
                parentStudentMapper.batchInsert(relations);
            }
        }
    }

    /**
     * 用户管理，更新家长信息
     * @param userParentDTO
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateParent(UserParentDTO userParentDTO) {
        if(userParentDTO.getPassword()!=null && !userParentDTO.getPassword().trim().isEmpty()){
            String password = userParentDTO.getPassword();
            String Jia_Mi_PWD = argon2.hash(2, 65536, 1, password.toCharArray());
            userParentDTO.setPassword(Jia_Mi_PWD);
        }else{
            userParentDTO.setPassword(null);
        }
        Parent parent = new Parent();
        BeanUtils.copyProperties(userParentDTO,parent);
        parentMapper.update(parent);

        parentStudentMapper.deleteByParentId(userParentDTO.getId());

        if(userParentDTO.getBindings()!=null && !userParentDTO.getBindings().isEmpty()){
            List<ParentStudent> relations = userParentDTO.getBindings().stream()
                    .filter(binding -> binding.getStudentId() != null && !String.valueOf(binding.getStudentId()).isEmpty())
                    .map(binding -> new ParentStudent(null, parent.getId(), binding.getStudentId()))
                    .collect(Collectors.toList());
            if (!relations.isEmpty()) {
                parentStudentMapper.batchInsert(relations);
            }
        }
    }

    /**
     * 单个删除家长信息
     * @param id
     */
    @Override
    public void deleteParent(Integer id) {
        Integer count = parentStudentMapper.countByParentId(Collections.singletonList(id));
        if(count>0){
            throw new BusinessException("该家长绑定了学生，无法删除，请先解除绑定");
        }
        parentMapper.deleteById(id);
    }

    @Override
    public void batchDeleteParentById(List<Integer> ids) {
        Integer count = parentStudentMapper.countByParentId(ids);
        if(count>0){
            throw new BusinessException("有家长绑定了学生，无法删除，请先解除绑定");
        }
        parentMapper.batchDeleteById(ids);
    }

}
